{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "outputs": [],
   "source": [
    "# LightGBMRegressor\n",
    "import pandas as pd\n",
    "import numpy as np\n",
    "from sklearn.model_selection import KFold\n",
    "from lightgbm.sklearn import LGBMRegressor\n",
    "from sklearn.metrics import mean_absolute_error\n",
    "\n",
    "# 首先使用 Pandas 库读入训练数据和测试数据，保存到 Train_data 和 Test_data 变量中。\n",
    "Train_data = pd.read_csv('train.csv',\n",
    "                         sep=' ')  # handle_used_car_train.csv\n",
    "Test_data = pd.read_csv('testB.csv', sep=' ')\n",
    "\n",
    "# 使用 pd.concat() 函数将训练数据和测试数据合并，并保存到 df 变量中。\n",
    "df = pd.concat([Train_data, Test_data], ignore_index=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "outputs": [],
   "source": [
    "# 对 'price' 做对数变换，使用 np.log1p() 函数。\n",
    "df['price'] = np.log1p(df['price'])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "outputs": [],
   "source": [
    "# 用众数填充缺失值\n",
    "df['fuelType'] = df['fuelType'].fillna(0)\n",
    "df['gearbox'] = df['gearbox'].fillna(0)\n",
    "df['bodyType'] = df['bodyType'].fillna(0)\n",
    "df['model'] = df['model'].fillna(0)\n",
    "\n",
    "# 处理异常值，主要是将功率大于 600 的标为 600\n",
    "df['power'] = df['power'].map(lambda x: 600 if x > 600 else x)  # 赛题限定power<=600\n",
    "# 将 ‘notRepairedDamage’ 中的缺失值替换为 None\n",
    "df['notRepairedDamage'] = df['notRepairedDamage'].astype('str').apply\n",
    "(lambda x: x if x != '-' else None).astype(\n",
    "    'float32')\n",
    "\n",
    "# 对可分类的连续特征进行分桶，例如将功率（power）分为 31 组，车型（model）分为 24 组。\n",
    "bin = [i * 10 for i in range(31)]\n",
    "df['power_bin'] = pd.cut(df['power'], bin, labels=False)\n",
    "\n",
    "bin = [i * 10 for i in range(24)]\n",
    "df['model_bin'] = pd.cut(df['model'], bin, labels=False)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "C:\\Users\\86186\\AppData\\Local\\Temp\\ipykernel_36148\\1521240310.py:33: FutureWarning: Passing a dictionary to SeriesGroupBy.agg is deprecated and will raise in a future version of pandas. Pass a list of aggregations instead.\n",
      "  t1 = Train_data.groupby(kk[0], as_index=False)[kk[1]].agg(\n"
     ]
    }
   ],
   "source": [
    "# 对日期数据进行处理，主要是提取年，月，日等信息和计算二手车使用时间。\n",
    "from datetime import datetime\n",
    "def date_process(x):\n",
    "    year = int(str(x)[:4])\n",
    "    month = int(str(x)[4:6])\n",
    "    day = int(str(x)[6:8])\n",
    "    if month < 1:\n",
    "        month = 1\n",
    "    date = datetime(year, month, day)\n",
    "    return date\n",
    "df['regDate'] = df['regDate'].apply(date_process)\n",
    "df['creatDate'] = df['creatDate'].apply(date_process)\n",
    "df['regDate_year'] = df['regDate'].dt.year\n",
    "df['regDate_month'] = df['regDate'].dt.month\n",
    "df['regDate_day'] = df['regDate'].dt.day\n",
    "df['creatDate_year'] = df['creatDate'].dt.year\n",
    "df['creatDate_month'] = df['creatDate'].dt.month\n",
    "df['creatDate_day'] = df['creatDate'].dt.day\n",
    "\n",
    "# 使用天数\n",
    "df['car_age_day'] = (df['creatDate'] - df['regDate']).dt.days\n",
    "# 使用年数\n",
    "df['car_age_year'] = round(df['car_age_day'] / 365, 1)\n",
    "\n",
    "# 对行驶路程和功率数据进行统计，例如：计算行驶路程与功率的最大值、最小值、中位数和均值等。\n",
    "kk = ['kilometer', 'power']\n",
    "t1 = Train_data.groupby(kk[0], as_index=False)[kk[1]].agg(\n",
    "    {kk[0] + '_' + kk[1] + '_count': 'count', kk[0] + '_' + kk[1] + '_max': 'max',\n",
    "     kk[0] + '_' + kk[1] + '_median': 'median',\n",
    "     kk[0] + '_' + kk[1] + '_min': 'min', kk[0] + '_' + kk[1] + '_sum': 'sum', kk[0] + '_' + kk[1] + '_std': 'std',\n",
    "     kk[0] + '_' + kk[1] + '_mean': 'mean'})\n",
    "df = pd.merge(df, t1, on=kk[0], how='left')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "outputs": [],
   "source": [
    "# 为部分属性列的数据生成新的特征，主要是通过对 V0、V3、V8 和 V12 四个特征进行组合生成新的二元和三元特征。\n",
    "num_cols = [0, 3, 8, 12]\n",
    "for i in num_cols:\n",
    "    for j in num_cols:\n",
    "        df['new' + str(i) + '*' + str(j)] = df['v_' + str(i)] * df['v_' + str(j)]\n",
    "\n",
    "for i in num_cols:\n",
    "    for j in num_cols:\n",
    "        df['new' + str(i) + '+' + str(j)] = df['v_' + str(i)] + df['v_' + str(j)]\n",
    "\n",
    "for i in num_cols:\n",
    "    for j in num_cols:\n",
    "        df['new' + str(i) + '-' + str(j)] = df['v_' + str(i)] - df['v_' + str(j)]\n",
    "\n",
    "for i in range(15):\n",
    "    df['new' + str(i) + '*year'] = df['v_' + str(i)] * df['car_age_year']"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "source": [
    "在训练模型的过程中，使用了 LightGBMRegressor 作为模型，采用四个参数（'n_estimators'、'learning_rate'、'num_leaves' 和 'lambda_l2'）进行调参。\n",
    "其中：\n",
    "'n_estimators'：表示树的数量，设置得越多，模型越复杂，训练得越慢。根据经验，一般取 100 至 10000 之间的数。\n",
    "\n",
    "'learning_rate'：表示学习率，是一个重要的参数，取值越小，需要的树的数量越多，训练得越慢，但一般能得到更好的性能。\n",
    "\n",
    "'num_leaves'：表示基分类器的数量，取值越大，模型的复杂度越高，但可能会导致过拟合。\n",
    "\n",
    "'lambda_l2'：表示 L2 正则化系数，取值越大，正则化效果越强，可以防止过拟合。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "--------------------- 第 1 折 ---------------------\n",
      "[LightGBM] [Warning] feature_fraction is set=0.8, colsample_bytree=1.0 will be ignored. Current value: feature_fraction=0.8\n",
      "[LightGBM] [Warning] lambda_l2 is set=2, reg_lambda=0.0 will be ignored. Current value: lambda_l2=2\n",
      "[LightGBM] [Warning] bagging_fraction is set=0.8, subsample=1.0 will be ignored. Current value: bagging_fraction=0.8\n",
      "[LightGBM] [Warning] bagging_freq is set=1, subsample_freq=0 will be ignored. Current value: bagging_freq=1\n",
      "[LightGBM] [Warning] feature_fraction is set=0.8, colsample_bytree=1.0 will be ignored. Current value: feature_fraction=0.8\n",
      "[LightGBM] [Warning] lambda_l2 is set=2, reg_lambda=0.0 will be ignored. Current value: lambda_l2=2\n",
      "[LightGBM] [Warning] bagging_fraction is set=0.8, subsample=1.0 will be ignored. Current value: bagging_fraction=0.8\n",
      "[LightGBM] [Warning] bagging_freq is set=1, subsample_freq=0 will be ignored. Current value: bagging_freq=1\n",
      "[LightGBM] [Info] Auto-choosing col-wise multi-threading, the overhead of testing was 0.050049 seconds.\n",
      "You can set `force_col_wise=true` to remove the overhead.\n",
      "[LightGBM] [Info] Total Bins 20391\n",
      "[LightGBM] [Info] Number of data points in the train set: 112500, number of used features: 98\n",
      "[LightGBM] [Warning] feature_fraction is set=0.8, colsample_bytree=1.0 will be ignored. Current value: feature_fraction=0.8\n",
      "[LightGBM] [Warning] lambda_l2 is set=2, reg_lambda=0.0 will be ignored. Current value: lambda_l2=2\n",
      "[LightGBM] [Warning] bagging_fraction is set=0.8, subsample=1.0 will be ignored. Current value: bagging_fraction=0.8\n",
      "[LightGBM] [Warning] bagging_freq is set=1, subsample_freq=0 will be ignored. Current value: bagging_freq=1\n",
      "[LightGBM] [Info] Start training from score 8.086718\n",
      "Training until validation scores don't improve for 300 rounds\n",
      "[300]\tvalid_0's l1: 0.127013\n",
      "[600]\tvalid_0's l1: 0.120945\n",
      "[900]\tvalid_0's l1: 0.118238\n",
      "[1200]\tvalid_0's l1: 0.11671\n",
      "[1500]\tvalid_0's l1: 0.115673\n",
      "[1800]\tvalid_0's l1: 0.114902\n",
      "[2100]\tvalid_0's l1: 0.114317\n",
      "[2400]\tvalid_0's l1: 0.113853\n",
      "[2700]\tvalid_0's l1: 0.113485\n",
      "[3000]\tvalid_0's l1: 0.113234\n",
      "[3300]\tvalid_0's l1: 0.113087\n",
      "[3600]\tvalid_0's l1: 0.11292\n",
      "[3900]\tvalid_0's l1: 0.112708\n",
      "[4200]\tvalid_0's l1: 0.112547\n",
      "[4500]\tvalid_0's l1: 0.112384\n",
      "[4800]\tvalid_0's l1: 0.112253\n",
      "[5100]\tvalid_0's l1: 0.112076\n",
      "[5400]\tvalid_0's l1: 0.111998\n",
      "[5700]\tvalid_0's l1: 0.111886\n",
      "[6000]\tvalid_0's l1: 0.111849\n",
      "[6300]\tvalid_0's l1: 0.111798\n",
      "[6600]\tvalid_0's l1: 0.111749\n",
      "[6900]\tvalid_0's l1: 0.111666\n",
      "[7200]\tvalid_0's l1: 0.111615\n",
      "[7500]\tvalid_0's l1: 0.111574\n",
      "[7800]\tvalid_0's l1: 0.111532\n",
      "[8100]\tvalid_0's l1: 0.111517\n",
      "Early stopping, best iteration is:\n",
      "[7900]\tvalid_0's l1: 0.111505\n",
      "[LightGBM] [Warning] feature_fraction is set=0.8, colsample_bytree=1.0 will be ignored. Current value: feature_fraction=0.8\n",
      "[LightGBM] [Warning] lambda_l2 is set=2, reg_lambda=0.0 will be ignored. Current value: lambda_l2=2\n",
      "[LightGBM] [Warning] bagging_fraction is set=0.8, subsample=1.0 will be ignored. Current value: bagging_fraction=0.8\n",
      "[LightGBM] [Warning] bagging_freq is set=1, subsample_freq=0 will be ignored. Current value: bagging_freq=1\n",
      "[LightGBM] [Warning] feature_fraction is set=0.8, colsample_bytree=1.0 will be ignored. Current value: feature_fraction=0.8\n",
      "[LightGBM] [Warning] lambda_l2 is set=2, reg_lambda=0.0 will be ignored. Current value: lambda_l2=2\n",
      "[LightGBM] [Warning] bagging_fraction is set=0.8, subsample=1.0 will be ignored. Current value: bagging_fraction=0.8\n",
      "[LightGBM] [Warning] bagging_freq is set=1, subsample_freq=0 will be ignored. Current value: bagging_freq=1\n",
      "--------------------- 第 2 折 ---------------------\n",
      "[LightGBM] [Warning] feature_fraction is set=0.8, colsample_bytree=1.0 will be ignored. Current value: feature_fraction=0.8\n",
      "[LightGBM] [Warning] lambda_l2 is set=2, reg_lambda=0.0 will be ignored. Current value: lambda_l2=2\n",
      "[LightGBM] [Warning] bagging_fraction is set=0.8, subsample=1.0 will be ignored. Current value: bagging_fraction=0.8\n",
      "[LightGBM] [Warning] bagging_freq is set=1, subsample_freq=0 will be ignored. Current value: bagging_freq=1\n",
      "[LightGBM] [Warning] feature_fraction is set=0.8, colsample_bytree=1.0 will be ignored. Current value: feature_fraction=0.8\n",
      "[LightGBM] [Warning] lambda_l2 is set=2, reg_lambda=0.0 will be ignored. Current value: lambda_l2=2\n",
      "[LightGBM] [Warning] bagging_fraction is set=0.8, subsample=1.0 will be ignored. Current value: bagging_fraction=0.8\n",
      "[LightGBM] [Warning] bagging_freq is set=1, subsample_freq=0 will be ignored. Current value: bagging_freq=1\n",
      "[LightGBM] [Info] Auto-choosing col-wise multi-threading, the overhead of testing was 0.045142 seconds.\n",
      "You can set `force_col_wise=true` to remove the overhead.\n",
      "[LightGBM] [Info] Total Bins 20391\n",
      "[LightGBM] [Info] Number of data points in the train set: 112500, number of used features: 98\n",
      "[LightGBM] [Warning] feature_fraction is set=0.8, colsample_bytree=1.0 will be ignored. Current value: feature_fraction=0.8\n",
      "[LightGBM] [Warning] lambda_l2 is set=2, reg_lambda=0.0 will be ignored. Current value: lambda_l2=2\n",
      "[LightGBM] [Warning] bagging_fraction is set=0.8, subsample=1.0 will be ignored. Current value: bagging_fraction=0.8\n",
      "[LightGBM] [Warning] bagging_freq is set=1, subsample_freq=0 will be ignored. Current value: bagging_freq=1\n",
      "[LightGBM] [Info] Start training from score 8.086718\n",
      "Training until validation scores don't improve for 300 rounds\n",
      "[300]\tvalid_0's l1: 0.125914\n",
      "[600]\tvalid_0's l1: 0.119853\n",
      "[900]\tvalid_0's l1: 0.117268\n",
      "[1200]\tvalid_0's l1: 0.11557\n",
      "[1500]\tvalid_0's l1: 0.11456\n",
      "[1800]\tvalid_0's l1: 0.113856\n",
      "[2100]\tvalid_0's l1: 0.113258\n",
      "[2400]\tvalid_0's l1: 0.112934\n",
      "[2700]\tvalid_0's l1: 0.112536\n",
      "[3000]\tvalid_0's l1: 0.11227\n",
      "[3300]\tvalid_0's l1: 0.112053\n",
      "[3600]\tvalid_0's l1: 0.111864\n",
      "[3900]\tvalid_0's l1: 0.111717\n",
      "[4200]\tvalid_0's l1: 0.111557\n",
      "[4500]\tvalid_0's l1: 0.111479\n",
      "[4800]\tvalid_0's l1: 0.111357\n",
      "[5100]\tvalid_0's l1: 0.111271\n",
      "[5400]\tvalid_0's l1: 0.111167\n",
      "[5700]\tvalid_0's l1: 0.111096\n",
      "[6000]\tvalid_0's l1: 0.111072\n",
      "[6300]\tvalid_0's l1: 0.111031\n",
      "[6600]\tvalid_0's l1: 0.110962\n",
      "[6900]\tvalid_0's l1: 0.110904\n",
      "[7200]\tvalid_0's l1: 0.110866\n",
      "[7500]\tvalid_0's l1: 0.110827\n",
      "[7800]\tvalid_0's l1: 0.110787\n",
      "[8100]\tvalid_0's l1: 0.110774\n",
      "[8400]\tvalid_0's l1: 0.110739\n",
      "[8700]\tvalid_0's l1: 0.110701\n",
      "[9000]\tvalid_0's l1: 0.110694\n",
      "[9300]\tvalid_0's l1: 0.110661\n",
      "[9600]\tvalid_0's l1: 0.110634\n",
      "[9900]\tvalid_0's l1: 0.11059\n",
      "Did not meet early stopping. Best iteration is:\n",
      "[9976]\tvalid_0's l1: 0.110581\n",
      "[LightGBM] [Warning] feature_fraction is set=0.8, colsample_bytree=1.0 will be ignored. Current value: feature_fraction=0.8\n",
      "[LightGBM] [Warning] lambda_l2 is set=2, reg_lambda=0.0 will be ignored. Current value: lambda_l2=2\n",
      "[LightGBM] [Warning] bagging_fraction is set=0.8, subsample=1.0 will be ignored. Current value: bagging_fraction=0.8\n",
      "[LightGBM] [Warning] bagging_freq is set=1, subsample_freq=0 will be ignored. Current value: bagging_freq=1\n",
      "[LightGBM] [Warning] feature_fraction is set=0.8, colsample_bytree=1.0 will be ignored. Current value: feature_fraction=0.8\n",
      "[LightGBM] [Warning] lambda_l2 is set=2, reg_lambda=0.0 will be ignored. Current value: lambda_l2=2\n",
      "[LightGBM] [Warning] bagging_fraction is set=0.8, subsample=1.0 will be ignored. Current value: bagging_fraction=0.8\n",
      "[LightGBM] [Warning] bagging_freq is set=1, subsample_freq=0 will be ignored. Current value: bagging_freq=1\n",
      "--------------------- 第 3 折 ---------------------\n",
      "[LightGBM] [Warning] feature_fraction is set=0.8, colsample_bytree=1.0 will be ignored. Current value: feature_fraction=0.8\n",
      "[LightGBM] [Warning] lambda_l2 is set=2, reg_lambda=0.0 will be ignored. Current value: lambda_l2=2\n",
      "[LightGBM] [Warning] bagging_fraction is set=0.8, subsample=1.0 will be ignored. Current value: bagging_fraction=0.8\n",
      "[LightGBM] [Warning] bagging_freq is set=1, subsample_freq=0 will be ignored. Current value: bagging_freq=1\n",
      "[LightGBM] [Warning] feature_fraction is set=0.8, colsample_bytree=1.0 will be ignored. Current value: feature_fraction=0.8\n",
      "[LightGBM] [Warning] lambda_l2 is set=2, reg_lambda=0.0 will be ignored. Current value: lambda_l2=2\n",
      "[LightGBM] [Warning] bagging_fraction is set=0.8, subsample=1.0 will be ignored. Current value: bagging_fraction=0.8\n",
      "[LightGBM] [Warning] bagging_freq is set=1, subsample_freq=0 will be ignored. Current value: bagging_freq=1\n",
      "[LightGBM] [Info] Auto-choosing col-wise multi-threading, the overhead of testing was 0.048347 seconds.\n",
      "You can set `force_col_wise=true` to remove the overhead.\n",
      "[LightGBM] [Info] Total Bins 20392\n",
      "[LightGBM] [Info] Number of data points in the train set: 112500, number of used features: 98\n",
      "[LightGBM] [Warning] feature_fraction is set=0.8, colsample_bytree=1.0 will be ignored. Current value: feature_fraction=0.8\n",
      "[LightGBM] [Warning] lambda_l2 is set=2, reg_lambda=0.0 will be ignored. Current value: lambda_l2=2\n",
      "[LightGBM] [Warning] bagging_fraction is set=0.8, subsample=1.0 will be ignored. Current value: bagging_fraction=0.8\n",
      "[LightGBM] [Warning] bagging_freq is set=1, subsample_freq=0 will be ignored. Current value: bagging_freq=1\n",
      "[LightGBM] [Info] Start training from score 8.086718\n",
      "Training until validation scores don't improve for 300 rounds\n",
      "[300]\tvalid_0's l1: 0.125105\n",
      "[600]\tvalid_0's l1: 0.119158\n",
      "[900]\tvalid_0's l1: 0.116389\n",
      "[1200]\tvalid_0's l1: 0.114748\n",
      "[1500]\tvalid_0's l1: 0.113613\n",
      "[1800]\tvalid_0's l1: 0.112848\n",
      "[2100]\tvalid_0's l1: 0.112232\n",
      "[2400]\tvalid_0's l1: 0.111795\n",
      "[2700]\tvalid_0's l1: 0.111457\n",
      "[3000]\tvalid_0's l1: 0.111166\n",
      "[3300]\tvalid_0's l1: 0.110891\n",
      "[3600]\tvalid_0's l1: 0.110651\n",
      "[3900]\tvalid_0's l1: 0.110441\n",
      "[4200]\tvalid_0's l1: 0.110282\n",
      "[4500]\tvalid_0's l1: 0.11013\n",
      "[4800]\tvalid_0's l1: 0.110016\n",
      "[5100]\tvalid_0's l1: 0.109923\n",
      "[5400]\tvalid_0's l1: 0.109799\n",
      "[5700]\tvalid_0's l1: 0.109746\n",
      "[6000]\tvalid_0's l1: 0.109647\n",
      "[6300]\tvalid_0's l1: 0.1096\n",
      "[6600]\tvalid_0's l1: 0.109564\n",
      "[6900]\tvalid_0's l1: 0.10949\n",
      "[7200]\tvalid_0's l1: 0.109446\n",
      "[7500]\tvalid_0's l1: 0.109431\n",
      "[7800]\tvalid_0's l1: 0.109383\n",
      "[8100]\tvalid_0's l1: 0.109327\n",
      "[8400]\tvalid_0's l1: 0.109266\n",
      "[8700]\tvalid_0's l1: 0.109225\n",
      "[9000]\tvalid_0's l1: 0.109195\n",
      "[9300]\tvalid_0's l1: 0.109171\n",
      "[9600]\tvalid_0's l1: 0.109158\n",
      "[9900]\tvalid_0's l1: 0.109124\n",
      "Did not meet early stopping. Best iteration is:\n",
      "[10000]\tvalid_0's l1: 0.109116\n",
      "[LightGBM] [Warning] feature_fraction is set=0.8, colsample_bytree=1.0 will be ignored. Current value: feature_fraction=0.8\n",
      "[LightGBM] [Warning] lambda_l2 is set=2, reg_lambda=0.0 will be ignored. Current value: lambda_l2=2\n",
      "[LightGBM] [Warning] bagging_fraction is set=0.8, subsample=1.0 will be ignored. Current value: bagging_fraction=0.8\n",
      "[LightGBM] [Warning] bagging_freq is set=1, subsample_freq=0 will be ignored. Current value: bagging_freq=1\n",
      "[LightGBM] [Warning] feature_fraction is set=0.8, colsample_bytree=1.0 will be ignored. Current value: feature_fraction=0.8\n",
      "[LightGBM] [Warning] lambda_l2 is set=2, reg_lambda=0.0 will be ignored. Current value: lambda_l2=2\n",
      "[LightGBM] [Warning] bagging_fraction is set=0.8, subsample=1.0 will be ignored. Current value: bagging_fraction=0.8\n",
      "[LightGBM] [Warning] bagging_freq is set=1, subsample_freq=0 will be ignored. Current value: bagging_freq=1\n",
      "--------------------- 第 4 折 ---------------------\n",
      "[LightGBM] [Warning] feature_fraction is set=0.8, colsample_bytree=1.0 will be ignored. Current value: feature_fraction=0.8\n",
      "[LightGBM] [Warning] lambda_l2 is set=2, reg_lambda=0.0 will be ignored. Current value: lambda_l2=2\n",
      "[LightGBM] [Warning] bagging_fraction is set=0.8, subsample=1.0 will be ignored. Current value: bagging_fraction=0.8\n",
      "[LightGBM] [Warning] bagging_freq is set=1, subsample_freq=0 will be ignored. Current value: bagging_freq=1\n",
      "[LightGBM] [Warning] feature_fraction is set=0.8, colsample_bytree=1.0 will be ignored. Current value: feature_fraction=0.8\n",
      "[LightGBM] [Warning] lambda_l2 is set=2, reg_lambda=0.0 will be ignored. Current value: lambda_l2=2\n",
      "[LightGBM] [Warning] bagging_fraction is set=0.8, subsample=1.0 will be ignored. Current value: bagging_fraction=0.8\n",
      "[LightGBM] [Warning] bagging_freq is set=1, subsample_freq=0 will be ignored. Current value: bagging_freq=1\n",
      "[LightGBM] [Info] Auto-choosing col-wise multi-threading, the overhead of testing was 0.048564 seconds.\n",
      "You can set `force_col_wise=true` to remove the overhead.\n",
      "[LightGBM] [Info] Total Bins 20388\n",
      "[LightGBM] [Info] Number of data points in the train set: 112500, number of used features: 98\n",
      "[LightGBM] [Warning] feature_fraction is set=0.8, colsample_bytree=1.0 will be ignored. Current value: feature_fraction=0.8\n",
      "[LightGBM] [Warning] lambda_l2 is set=2, reg_lambda=0.0 will be ignored. Current value: lambda_l2=2\n",
      "[LightGBM] [Warning] bagging_fraction is set=0.8, subsample=1.0 will be ignored. Current value: bagging_fraction=0.8\n",
      "[LightGBM] [Warning] bagging_freq is set=1, subsample_freq=0 will be ignored. Current value: bagging_freq=1\n",
      "[LightGBM] [Info] Start training from score 8.086718\n",
      "Training until validation scores don't improve for 300 rounds\n",
      "[300]\tvalid_0's l1: 0.126819\n",
      "[600]\tvalid_0's l1: 0.120085\n",
      "[900]\tvalid_0's l1: 0.117448\n",
      "[1200]\tvalid_0's l1: 0.115594\n",
      "[1500]\tvalid_0's l1: 0.114612\n",
      "[1800]\tvalid_0's l1: 0.113984\n",
      "[2100]\tvalid_0's l1: 0.113421\n",
      "[2400]\tvalid_0's l1: 0.112969\n",
      "[2700]\tvalid_0's l1: 0.112555\n",
      "[3000]\tvalid_0's l1: 0.11219\n",
      "[3300]\tvalid_0's l1: 0.11192\n",
      "[3600]\tvalid_0's l1: 0.111679\n",
      "[3900]\tvalid_0's l1: 0.111524\n",
      "[4200]\tvalid_0's l1: 0.111372\n",
      "[4500]\tvalid_0's l1: 0.111231\n",
      "[4800]\tvalid_0's l1: 0.111083\n",
      "[5100]\tvalid_0's l1: 0.110961\n",
      "[5400]\tvalid_0's l1: 0.110841\n",
      "[5700]\tvalid_0's l1: 0.110771\n",
      "[6000]\tvalid_0's l1: 0.110701\n",
      "[6300]\tvalid_0's l1: 0.11063\n",
      "[6600]\tvalid_0's l1: 0.110551\n",
      "[6900]\tvalid_0's l1: 0.110503\n",
      "[7200]\tvalid_0's l1: 0.110406\n",
      "[7500]\tvalid_0's l1: 0.11035\n",
      "[7800]\tvalid_0's l1: 0.110292\n",
      "[8100]\tvalid_0's l1: 0.110256\n",
      "[8400]\tvalid_0's l1: 0.110197\n",
      "[8700]\tvalid_0's l1: 0.110173\n",
      "[9000]\tvalid_0's l1: 0.11017\n",
      "[9300]\tvalid_0's l1: 0.110127\n",
      "[9600]\tvalid_0's l1: 0.110088\n",
      "[9900]\tvalid_0's l1: 0.110072\n",
      "Did not meet early stopping. Best iteration is:\n",
      "[9883]\tvalid_0's l1: 0.110066\n",
      "[LightGBM] [Warning] feature_fraction is set=0.8, colsample_bytree=1.0 will be ignored. Current value: feature_fraction=0.8\n",
      "[LightGBM] [Warning] lambda_l2 is set=2, reg_lambda=0.0 will be ignored. Current value: lambda_l2=2\n",
      "[LightGBM] [Warning] bagging_fraction is set=0.8, subsample=1.0 will be ignored. Current value: bagging_fraction=0.8\n",
      "[LightGBM] [Warning] bagging_freq is set=1, subsample_freq=0 will be ignored. Current value: bagging_freq=1\n",
      "[LightGBM] [Warning] feature_fraction is set=0.8, colsample_bytree=1.0 will be ignored. Current value: feature_fraction=0.8\n",
      "[LightGBM] [Warning] lambda_l2 is set=2, reg_lambda=0.0 will be ignored. Current value: lambda_l2=2\n",
      "[LightGBM] [Warning] bagging_fraction is set=0.8, subsample=1.0 will be ignored. Current value: bagging_fraction=0.8\n",
      "[LightGBM] [Warning] bagging_freq is set=1, subsample_freq=0 will be ignored. Current value: bagging_freq=1\n",
      "交叉验证 MAE: 472.94900133697445\n"
     ]
    }
   ],
   "source": [
    "# 使用 LightGBMRegressor 作为模型，对数据进行训练和预测。\n",
    "# 对数据进行五折交叉检验，最后通过将五次模型训练得到的结果平均作为最终预测结果，并将结果保存到文件中供提交。\n",
    "from lightgbm import early_stopping, log_evaluation\n",
    "df1 = df.copy()\n",
    "test = df1[df1['price'].isnull()]\n",
    "X_train = df1[df1['price'].notnull()].drop(['price', 'regDate', 'creatDate', 'SaleID', 'regionCode'], axis=1)\n",
    "Y_train = df1[df1['price'].notnull()]['price']\n",
    "X_test = df1[df1['price'].isnull()].drop(['price', 'regDate', 'creatDate', 'SaleID', 'regionCode'], axis=1)\n",
    "# 五折交叉检验\n",
    "cols = list(X_train)\n",
    "oof = np.zeros(X_train.shape[0])\n",
    "sub = test[['SaleID']].copy()\n",
    "sub['price'] = 0\n",
    "feat_df = pd.DataFrame({'feat': cols, 'imp': 0})\n",
    "skf = KFold(n_splits=4, shuffle=True, random_state=2020)\n",
    "\n",
    "clf = LGBMRegressor(\n",
    "    n_estimators=10000,\n",
    "    learning_rate=0.07,  # 0.02,\n",
    "    boosting_type='gbdt',\n",
    "    objective='regression_l1',\n",
    "    max_depth=-1,\n",
    "    num_leaves=31,\n",
    "    min_child_samples=20,\n",
    "    feature_fraction=0.8,\n",
    "    bagging_freq=1,\n",
    "    bagging_fraction=0.8,\n",
    "    lambda_l2=2,\n",
    "    random_state=2020,\n",
    "    metric='mae'\n",
    ")\n",
    "\n",
    "mae = 0\n",
    "\n",
    "callbacks = [log_evaluation(period=300), early_stopping(stopping_rounds=300)]\n",
    "for i, (trn_idx, val_idx) in enumerate(skf.split(X_train, Y_train)):\n",
    "    print('--------------------- 第 {} 折 ---------------------'.format(i + 1))\n",
    "    trn_x, trn_y = X_train.iloc[trn_idx].reset_index(drop=True), Y_train[trn_idx]\n",
    "    val_x, val_y = X_train.iloc[val_idx].reset_index(drop=True), Y_train[val_idx]\n",
    "    clf.fit(\n",
    "        trn_x, trn_y,\n",
    "        eval_set=[(val_x, val_y)],\n",
    "        eval_metric='mae',\n",
    "        callbacks=callbacks,\n",
    "    )\n",
    "\n",
    "    sub['price'] += np.expm1(clf.predict(X_test)) / skf.n_splits\n",
    "    oof[val_idx] = clf.predict(val_x)\n",
    "    mae += mean_absolute_error(np.expm1(val_y), np.expm1(oof[val_idx])) / skf.n_splits\n",
    "\n",
    "print('交叉验证 MAE:', mae)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "outputs": [],
   "source": [
    "# 生成提交文件\n",
    "sub.to_csv('submit.csv', index=False)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.12.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
